const fs = require('fs').promises;
const path = require('path');
const crypto = require('crypto');

class FileCache {
  constructor() {
    this.cacheDir = path.join(__dirname, '../data/cache');
    this.MAX_CACHE_SIZE = 500 * 1024 * 1024; // 500MB
    this.MAX_FILES = 50000; // 最多50000个文件
    this.init();
  }

  async init() {
    try {
      await fs.mkdir(this.cacheDir, { recursive: true });
      console.log('缓存目录初始化成功:', this.cacheDir);
    } catch (error) {
      console.error('创建缓存目录失败:', error);
    }
  }

  // 生成缓存文件名
  _getCacheKey(type, parameters) {
    const key = type + '_' + (parameters.query || parameters.category);
    return crypto.createHash('md5').update(key).digest('hex');
  }

  // 获取缓存文件路径
  _getCachePath(type, parameters) {
    const key = this._getCacheKey(type, parameters);
    return path.join(this.cacheDir, `${key}.json`);
  }

  // 获取缓存
  async getCard(type, parameters) {
    try {
      const cachePath = this._getCachePath(type, parameters);
      const data = await fs.readFile(cachePath, 'utf8');
      const card = JSON.parse(data);
      
      // 更新访问信息
      card.lastAccessed = new Date().toISOString();
      card.accessCount += 1;
      await this.saveCard(type, parameters, card);
      
      console.log(`缓存命中: ${type} - ${parameters.query || parameters.category}`);
      return {
        type: card.type,
        title: card.title,
        content: card.content,
        timestamp: card.timestamp
      };
    } catch (error) {
      console.log(`缓存未命中: ${type} - ${parameters.query || parameters.category}`);
      return null;
    }
  }

  // 保存缓存
  async saveCard(type, parameters, cardData) {
    try {
      // 检查缓存大小
      const stats = await fs.stat(this.cacheDir);
      if (stats.size > this.MAX_CACHE_SIZE) {
        console.log('缓存大小超过限制，开始清理...');
        await this.cleanupCache();
      }

      // 检查文件数量
      const files = await fs.readdir(this.cacheDir);
      if (files.length >= this.MAX_FILES) {
        console.log('缓存文件数量超过限制，开始清理...');
        await this.cleanupCache();
      }

      const cachePath = this._getCachePath(type, parameters);
      const data = {
        ...cardData,
        type,
        query: parameters.query,
        category: parameters.category,
        timestamp: new Date().toISOString(),
        lastAccessed: new Date().toISOString(),
        accessCount: (cardData.accessCount || 0) + 1
      };
      
      await fs.writeFile(cachePath, JSON.stringify(data, null, 2));
      console.log(`缓存保存成功: ${type} - ${parameters.query || parameters.category}`);
    } catch (error) {
      console.error('保存缓存失败:', error);
    }
  }

  // 清理过期缓存
  async cleanupCache(maxAge = 30 * 24 * 60 * 60 * 1000) { // 默认30天
    try {
      const files = await fs.readdir(this.cacheDir);
      const now = Date.now();
      
      // 获取所有文件信息
      const fileStats = await Promise.all(
        files.map(async file => {
          const filePath = path.join(this.cacheDir, file);
          const data = JSON.parse(await fs.readFile(filePath, 'utf8'));
          return {
            file,
            filePath,
            lastAccessed: new Date(data.lastAccessed).getTime(),
            accessCount: data.accessCount,
            size: (await fs.stat(filePath)).size
          };
        })
      );

      // 按访问次数和最后访问时间排序
      fileStats.sort((a, b) => {
        if (a.accessCount !== b.accessCount) {
          return a.accessCount - b.accessCount;
        }
        return a.lastAccessed - b.lastAccessed;
      });

      // 删除最不常用的文件，直到缓存大小合适
      let currentSize = (await fs.stat(this.cacheDir)).size;
      let deletedCount = 0;
      
      for (const file of fileStats) {
        if (currentSize <= this.MAX_CACHE_SIZE * 0.8) break; // 清理到80%容量
        
        await fs.unlink(file.filePath);
        currentSize -= file.size;
        deletedCount++;
      }

      console.log(`缓存清理完成，删除了 ${deletedCount} 个文件，当前大小: ${(currentSize / 1024 / 1024).toFixed(2)}MB`);
    } catch (error) {
      console.error('清理缓存失败:', error);
    }
  }

  // 获取缓存统计信息
  async getStats() {
    try {
      const files = await fs.readdir(this.cacheDir);
      const stats = {
        totalFiles: files.length,
        totalSize: 0,
        typeStats: {},
        lastAccessed: null,
        mostAccessed: null
      };

      for (const file of files) {
        const filePath = path.join(this.cacheDir, file);
        const data = JSON.parse(await fs.readFile(filePath, 'utf8'));
        const fileSize = (await fs.stat(filePath)).size;

        stats.totalSize += fileSize;
        
        // 统计各类型数量
        stats.typeStats[data.type] = (stats.typeStats[data.type] || 0) + 1;

        // 更新最后访问时间
        const lastAccessed = new Date(data.lastAccessed);
        if (!stats.lastAccessed || lastAccessed > new Date(stats.lastAccessed)) {
          stats.lastAccessed = data.lastAccessed;
        }

        // 更新最多访问次数
        if (!stats.mostAccessed || data.accessCount > stats.mostAccessed.count) {
          stats.mostAccessed = {
            type: data.type,
            query: data.query || data.category,
            count: data.accessCount
          };
        }
      }

      stats.totalSizeMB = (stats.totalSize / 1024 / 1024).toFixed(2);
      return stats;
    } catch (error) {
      console.error('获取缓存统计信息失败:', error);
      return null;
    }
  }
}

module.exports = new FileCache(); 